using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Notification = Ursa.Controls.Notification;
using WindowNotificationManager = Ursa.Controls.WindowNotificationManager;

namespace Digitalmes.AvaloniaUI.Infrastructure;

/// <summary>
/// ViewModel 基础类，实现该类的对象会被注入到服务中。
/// </summary>
public abstract class ViewModelBase : ObservableObject, IViewToViewModelBridge, IDisposable
{
    private bool _disposedValue;

    private WindowToastManager? _toastManager;
    private WindowNotificationManager? _notificationManager;

    private readonly WeakReference<Visual?> _visualRef = new(default);

    Visual? IViewToViewModelBridge.View
    {
        get => _visualRef.TryGetTarget(out var target) ? target : default;
        set  
        { 
            _visualRef.SetTarget(value);
        }
    }

    /// <summary>
    /// 通过 ViewLocator，将 View 注入 ViewModel 中，以便能获取 TopLevel。
    /// </summary>
    public TopLevel? TopLevel
    {
        get
        {
            if (_visualRef.TryGetTarget(out var view) && view is not null)
            {
                return TopLevel.GetTopLevel(view);
            }
            return default;
        }
    }

    /// <summary>
    /// 显示提示消息。
    /// </summary>
    /// <param name="message">要显示的消息</param>
    /// <param name="notificationType">消息类型</param>
    public void ShowToast(string message, NotificationType notificationType = NotificationType.Success)
    {
        _toastManager ??= new(TopLevel) { MaxItems = 3 };
        _toastManager.Show(
                new Toast(message),
                showIcon: false,
                showClose: false,
                type: notificationType,
                expiration: TimeSpan.FromSeconds(3),
                classes: ["Light"]);
    }

    /// <summary>
    /// 显示通知消息。
    /// </summary>
    /// <param name="title">消息标题</param>
    /// <param name="content">消息内容</param>
    /// <param name="notificationType">消息类型</param>
    public void ShowNotification(string? title, string? content, NotificationType notificationType = NotificationType.Success)
    {
        if (_notificationManager == null && TopLevel != null)
        {
            _notificationManager = new WindowNotificationManager(TopLevel)
            {
                Position = NotificationPosition.TopCenter,
                MaxItems = 3,
            };
        }

        _notificationManager?.Show(
            new Notification(title, content),
            notificationType,
            expiration: TimeSpan.FromSeconds(5),
            showClose: false,
            classes: ["Light"]);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposedValue)
        {
            if (disposing)
            {
                _notificationManager?.Uninstall();
            }
            
            _disposedValue = true;
        }
    }

    public virtual void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
